TreeviewCopyright © aleen42 all right reserved, powered by aleen42

我们知道,Android 中提供了一些提示控件,例如 ToastSnackbarAlertDialog 等,Flutter 也有类似的 Widget,下面来一一讲解:

Snackbar

和 Toast 类似,Snackbar 用于显示一些提示信息,可以自动隐藏,和 Toast 不同的是还可以添加一些按钮操作。在 Flutter 中,Snackbar 是通过 ScaffoldshowSnackBar 方法来显示的。所以要显示一个 SnackBar,需要先拿到一个 Scaffold 对象。

先看 Snackbar 的属性:

  const SnackBar({
    Key key,
    @required this.content,     //Snackbar 内容
    this.backgroundColor,    //Snackbar 背景色
    this.elevation,    // 阴影高度
    this.shape,    //背景形状,类似于 Android 中的 shape
    this.behavior,    //fixed 固定在底部,弹出时会把页面上顶;floating 悬浮在页面上方
    this.action,    //添加操作
    this.duration = _snackBarDisplayDuration,    //Snackbar 显示时间,默认 4000 毫秒
    this.animation,    //Snackbar 的进出动画
  })

使用起来也很简单:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("SnackBar"),
      ),
      body: new Center(
        child: new Builder(builder: (BuildContext context) {
          return new RaisedButton(
            onPressed: () {
              Scaffold.of(context).showSnackBar(new SnackBar(
                content: new Text("下载成功"),
                backgroundColor: Colors.amber,
                elevation: 20,
                shape: new RoundedRectangleBorder(
                    borderRadius: new BorderRadius.circular(30.0)),
                behavior: SnackBarBehavior.floating,
                action: new SnackBarAction(
                  label: "知道了",
                  onPressed: () {
                    //移除 Snackbar
                    Scaffold.of(context).removeCurrentSnackBar();
                  },
                ),
                duration: Duration(seconds: 5),
              ));
            },
            child: new Text("SnackBar提示"),
            color: Colors.cyan,
            highlightColor: Colors.lightBlueAccent,
            disabledColor: Colors.lightBlueAccent,
          );
        }),
      ),
    );
  }
}

使用 Snackbar 有两点需要注意:

  1. 值得注意的是 Scaffold.of(context) 这个 context 必须不能是 Scaffold 节点下的 context,因为Scaffold.of() 方法需要从 Widget 树中去找到 Scaffold 的 Context,所以如果直接在 Scaffold 中使用 showSnackBar, 需要在外城包括上 Builder Widget,这个 Builder 不做任何的其他操作,只不过把 Widget 树往下移了一层而已。
  2. Snackbar 默认显示时间是 4 秒,如果你一下子弹出多个 Snackbar,消息会以队列的形式一个一个发出,这样的效果很不友好,所以我们通常会在显示一个 Snackbar 之前,先将之前的移除,调用 Scaffold.of(context).removeCurrentSnackBar(); 即可。

Tooltip

这个 Widget 我没觉得有啥用,它的作用是你传入一个控件作为参数,长按这个控件,会在这个控件的上方显示一个提示。

看源码:

  const Tooltip({
    Key key,
    @required this.message,    //提示内容
    this.height = _defaultTooltipHeight,    //提示框默认高度
    this.padding = _defaultPadding,    //提示框的 padding
    this.verticalOffset = _defaultVerticalOffset,    //提示框和 child 组件的距离
    this.preferBelow = true,    //提示框是否显示在 child 控件下面
    this.excludeFromSemantics = false,    //Semantics 语义控件,辅助控件相关
    this.decoration,    //提示框的装饰
    this.waitDuration = _defaultWaitDuration,    //默认需要长按多久才显示提示框
    this.showDuration = _defaultShowDuration,    //默认提示框显示时间
    this.child,    //显示的控件
  })

例子就不上了,很简单。

Dialog

在 Flutter 中 Dialog 主要有三种形式:

  • AlertDialog
  • SimpleDialog

Flutter 提供了一个 showDialog 方法来显示 Dialog,看一下这个方法的源码:

Future<T> showDialog<T>({
  @required BuildContext context,
  bool barrierDismissible = true,
  @Deprecated(
    'Instead of using the "child" argument, return the child from a closure '
    'provided to the "builder" argument. This will ensure that the BuildContext '
    'is appropriate for widgets built in the dialog.'
  ) Widget child,
  WidgetBuilder builder,
}){
    ...//方法体省略了
}

可以看到这个方法接收三个参数:

  1. context,这个不用说了
  2. barrierDismissible,点击 Dialog 之外的区域是否隐藏 Dialog
  3. child[已弃用,改为 builder]
  4. builder,需要返回一个 Widget,这个 Widget 会被作为 Dialog 展示在页面上

从最后一个参数可以看出来,这个 “Dialog” 并不一定就是一个 “Dialog”(好绕口),它可以是一个按钮,一个 Icon,一个 Text。

但在 Flutter 中使用最多的,还是 SimpleDialog 和 AlertDialog。

SimpleDialog

会向用户展示一个提供多个选项的 Dialog,通常选项由一个个 SimpleDialogOption 来组成

看源码:

  const SimpleDialog({
    Key key,
    this.title,    //标题
    this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),    //标题的 padding
    this.children,    //内容
    this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),//内容 padding
    this.backgroundColor,    //背景色
    this.elevation,    //阴影
    this.semanticLabel,    //和语音助手相关
    this.shape,    //背景形状,类似于 Android 中的 shape
  }){
      //方法体省略
  }

使用起来也很简单:

showDialog(
    context: context,
    barrierDismissible: false,
    builder: (context) {
        return SimpleDialog(
            title: Center(
                child: Row(
                    children: <Widget>[
                        Icon(Icons.account_circle),
                        Text("请选择您的性别:"),
                    ],
                ),
            ),
            children: <Widget>[
                new SimpleDialogOption(
                    child: new Text("男"),
                    onPressed: () {
                        Navigator.of(context).pop(1);
                    },
                ),
                new SimpleDialogOption(
                    child: new Text("女"),
                    onPressed: () {
                        Navigator.of(context).pop(0);
                    },
                ),
            ],
        );
    })

AlertDialog

如果你需要向用户通知一些信息,可以选择使用 AlertDialog,看源码:

  const AlertDialog({
    Key key,
    this.title,    //标题
    this.titlePadding,    //标题 padding
    this.titleTextStyle,    //标题文字 style
    this.content,    //内容
    this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),    //内容 padding
    this.contentTextStyle,    //内容文字 Style
    this.actions,    //操作
    this.backgroundColor,    //背景色
    this.elevation,    //阴影
    this.semanticLabel,    //和语音助手相关
    this.shape,    //背景形状,类似于 Android 中的 shape
  })

这个使用起来更简单了:

showDialog(
    context: context,
    barrierDismissible: false,
    builder: (context) {
        return AlertDialog(
            title: Center(
                child: Row(
                    children: <Widget>[
                        Icon(Icons.account_circle),
                        Text("您的电量低:"),
                    ],
                ),
            ),
            content: Text("请及时充电"),
            actions: <Widget>[
                MaterialButton(
                    child: Text("知道了"),
                    onPressed: () {
                        Navigator.of(context).pop();
                    },
                ),
            ],
        );
    });

results matching ""

    No results matching ""